/*!
 * \file pool.hpp
 * \brief 线程池核心实现
 *
 * \details 此文件包含线程池的核心类：pool<Task, SchedulingPolicy>。
 *          
 *          线程池是在同一进程内进行异步和并行处理的机制。pool类提供了
 *          一种方便的方式来分发异步任务作为函数对象。这些任务的调度
 *          可以通过使用自定义的调度器轻松控制。
 *          
 *          核心特性：
 *          - 模板化设计，支持不同任务类型和调度策略
 *          - 线程安全的任务提交和管理
 *          - 可配置的线程池大小策略
 *          - 支持任务优先级和不同调度算法
 *          - 提供同步等待机制
 *          - 基于RAII的资源管理
 *          
 *          适用场景：
 *          - 高频交易系统的并行计算
 *          - 数据处理的任务分发
 *          - I/O密集型操作的异步处理
 *          - 网络服务的请求处理
 *
 * Copyright (c) 2005-2007 Philipp Henkel
 *
 * Use, modification, and distribution are  subject to the
 * Boost Software License, Version 1.0. (See accompanying  file
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 * http://threadpool.sourceforge.net
 *
 */


#ifndef THREADPOOL_POOL_HPP_INCLUDED
#define THREADPOOL_POOL_HPP_INCLUDED

#include <boost/ref.hpp>

#include "./detail/pool_core.hpp"

#include "task_adaptors.hpp"

#include "./detail/locking_ptr.hpp"

#include "scheduling_policies.hpp"
#include "size_policies.hpp"
#include "shutdown_policies.hpp"



/*!
 * \brief threadpool命名空间包含线程池和相关的工具类
 * 
 * \details 提供完整的线程池解决方案，包括：
 *          - 核心线程池实现
 *          - 各种调度策略
 *          - 任务适配器
 *          - 大小管理策略
 *          - 关闭策略
 */
namespace boost { namespace threadpool
{



  /*!
   * \brief 线程池模板类
   *
   * \details 线程池是在同一进程内进行异步和并行处理的机制。pool类提供了
   *          一种方便的方式来分发异步任务作为函数对象。这些任务的调度
   *          可以通过使用自定义的调度器轻松控制。任务不能抛出异常。
   *
   *          pool是默认可构造、可拷贝构造和可赋值的。它具有引用语义；
   *          同一个pool的所有副本都是等价和可互换的。除了赋值操作外，
   *          pool上的所有操作都是强线程安全或顺序一致的；也就是说，
   *          并发调用的行为就像这些调用以未指定的顺序顺序发出一样。
   *
   * \tparam Task 实现operator 'void operator() (void) const'的函数对象。
   *              pool调用operator()来执行任务。异常将被忽略。
   * \tparam SchedulingPolicy 确定如何调度任务的任务容器。保证此容器
   *                          一次只能被一个线程访问。调度器不能抛出异常。
   * \tparam SizePolicy 线程池大小管理策略
   * \tparam SizePolicyController 大小策略控制器
   * \tparam ShutdownPolicy 关闭策略
   *
   * \remarks pool类是线程安全的。
   * 
   * \see 任务类型: task_func, prio_task_func
   * \see 调度策略: fifo_scheduler, lifo_scheduler, prio_scheduler
   */ 
  template <
    typename Task                                   = task_func,
    template <typename> class SchedulingPolicy      = fifo_scheduler,
    template <typename> class SizePolicy            = static_size,
    template <typename> class SizePolicyController  = resize_controller,
    template <typename> class ShutdownPolicy        = wait_for_all_tasks
  > 
  class thread_pool 
  {
    typedef detail::pool_core<Task, 
                              SchedulingPolicy,
                              SizePolicy,
                              SizePolicyController,
                              ShutdownPolicy> pool_core_type;
    shared_ptr<pool_core_type>          m_core; //!< pimpl idiom，核心实现的智能指针
    shared_ptr<void>                    m_shutdown_controller; //!< 如果删除持有核心指针的最后一个pool，控制器将关闭池

  public: // 类型定义
    typedef Task task_type;                                   //!< 指示任务的类型
    typedef SchedulingPolicy<task_type> scheduler_type;       //!< 指示调度器的类型
 /*   typedef thread_pool<Task, 
                        SchedulingPolicy,
                        SizePolicy,
                        ShutdownPolicy > pool_type;          //!< 指示线程池的类型
 */
    typedef SizePolicy<pool_core_type> size_policy_type;      //!< 大小策略类型
    typedef SizePolicyController<pool_core_type> size_controller_type; //!< 大小控制器类型


  public:
    /*!
     * \brief 构造函数
     * \param initial_threads 立即将池调整为指定的线程数。池的实际线程数取决于SizePolicy。
     * 
     * \details 创建一个新的线程池实例，初始化核心组件和关闭控制器。
     *          使用RAII机制确保当所有pool引用都被销毁时自动关闭线程池。
     */
    thread_pool(size_t initial_threads = 0)
    : m_core(new pool_core_type)
    , m_shutdown_controller(static_cast<void*>(0), bind(&pool_core_type::shutdown, m_core))
    {
      size_policy_type::init(*m_core, initial_threads);
    }


    /*!
     * \brief 获取管理池中线程数的大小控制器
     * \return 大小控制器
     * \see SizePolicy
     * 
     * \details 返回用于动态控制线程池大小的控制器对象，
     *          可以用来运行时调整线程数量。
     */
    size_controller_type size_controller()
    {
      return m_core->size_controller();
    }


    /*!
     * \brief 获取池中的线程数
     * \return 线程数
     * 
     * \details 返回当前线程池中活跃的工作线程数量。
     *          这个值可能根据大小策略动态变化。
     */
    size_t size()	const
    {
      return m_core->size();
    }


     /*!
      * \brief 调度任务进行异步执行
      * \param task 任务函数对象。它不应该抛出异常。
      * \return 如果任务可以被调度则返回true，否则返回false
      * 
      * \details 将任务添加到调度队列中，由工作线程异步执行。
      *          任务只会被执行一次。如果线程池已关闭或队列已满，
      *          可能返回false。
      */  
     bool schedule(task_type const & task)
     {	
       return m_core->schedule(task);
     }


    /*!
     * \brief 返回当前正在执行的任务数
     * \return 活跃任务数
     * 
     * \details 获取当前正在工作线程中执行的任务数量。
     *          这个值实时反映线程池的负载情况。
     */  
    size_t active() const
    {
      return m_core->active();
    }


    /*!
     * \brief 返回准备执行的任务数
     * \return 待处理任务数
     * 
     * \details 获取在调度队列中等待执行的任务数量。
     *          高的待处理数可能表明需要增加线程数。
     */  
    size_t pending() const
    {
      return m_core->pending();
    }


    /*!
     * \brief 从池的调度器中移除所有待处理任务
     * 
     * \details 清空任务队列，但不影响当前正在执行的任务。
     *          这对于重置线程池状态很有用。
     */  
    void clear()
    { 
      m_core->clear();
    }    


    /*!
     * \brief 指示是否没有待处理任务
     * \return 如果没有准备执行的任务则返回true
     * 
     * \remarks 这个函数比检查'pending() == 0'更高效。
     * 
     * \details 快速检查任务队列是否为空。这比调用pending()
     *          然后比较更高效，特别是在高频调用场景中。
     */   
    bool empty() const
    {
      return m_core->empty();
    }	


    /*!
     * \brief 阻塞当前执行线程直到活跃和待处理任务总数小于等于给定阈值
     * \param task_threshold 池和调度器中的最大任务数
     * 
     * \details 同步等待机制，用于确保任务完成。在需要等待所有任务
     *          完成或任务数降到特定水平时使用。默认阈值0表示等待
     *          所有任务完成。
     */     
    void wait(size_t task_threshold = 0) const
    {
      m_core->wait(task_threshold);
    }	


    /*!
     * \brief 阻塞当前执行线程直到满足时间戳或任务总数小于等于给定阈值
     * \param timestamp 函数最晚返回的时间
     * \param task_threshold 池和调度器中的最大任务数
     * \return 如果任务总数小于等于阈值则返回true，否则返回false
     * 
     * \details 带超时的同步等待机制。如果在指定时间内任务数降到
     *          阈值以下则返回true，否则超时返回false。这对于
     *          避免无限等待很有用。
     */       
    bool wait(xtime const & timestamp, size_t task_threshold = 0) const
    {
      return m_core->wait(timestamp, task_threshold);
    }
  };



  /*!
   * \brief FIFO池
   *
   * \details 池的任务是FIFO调度的task_func函数对象。
   *          任务按照先进先出的顺序执行，适合大多数常规场景。
   *
   */ 
  typedef thread_pool<task_func, fifo_scheduler, static_size, resize_controller, wait_for_all_tasks> fifo_pool;


  /*!
   * \brief LIFO池
   *
   * \details 池的任务是LIFO调度的task_func函数对象。
   *          任务按照后进先出的顺序执行，适合栈式处理场景。
   *
   */ 
  typedef thread_pool<task_func, lifo_scheduler, static_size, resize_controller, wait_for_all_tasks> lifo_pool;


  /*!
   * \brief 优先级任务池
   *
   * \details 池的任务是优先级调度的prio_task_func函数对象。
   *          任务按照优先级顺序执行，高优先级任务优先处理。
   *          适合需要任务优先级区分的场景。
   *
   */ 
  typedef thread_pool<prio_task_func, prio_scheduler, static_size, resize_controller, wait_for_all_tasks> prio_pool;


  /*!
   * \brief 标准池
   *
   * \details 池的任务是FIFO调度的task_func函数对象。
   *          这是默认的线程池类型，提供标准的FIFO任务处理。
   *
   */ 
  typedef fifo_pool pool;



} } // namespace boost::threadpool

#endif // THREADPOOL_POOL_HPP_INCLUDED
